// 导入electron对象
// app 控制应用程序的事件生命周期。
// BrowserWindow 创建并控制浏览器窗口。
const {app, BrowserWindow, Menu, ipcMain, Tray} = require('electron')
const net = require('net');
// 开启热加载
const reLoader = require('electron-reloader')
reLoader(module)

// 禁用硬件加速
app.disableHardwareAcceleration();
app.commandLine.appendSwitch('use-angle', 'gl');

const dgram = require('dgram');

// 创建 UDP 套接字
const client = dgram.createSocket('udp4');
let mainWindow = null
let tray = null

const createWindow = () => {
    // 确保窗口不会被多次创建
    if (mainWindow === null) {
        mainWindow = new BrowserWindow({
            title: '零点房控终端',
            width: 700,
            height: 625,
            frame: true,
            icon: __dirname + '/public/favicon.ico', // 确认图标路径是否正确
            webPreferences: {
                nodeIntegration: true, // 启用 Node.js 集成
                contextIsolation: false, // 禁用上下文隔离
            },
        });

        // 创建系统托盘图标
        tray = new Tray(__dirname + '/public/hslog.png')  // 确认托盘图标路径
        tray.setToolTip('零点房控终端') // 设置托盘提示

        // 创建托盘右键菜单
        const contextMenu = Menu.buildFromTemplate([
            {label: '打开应用', click: () => mainWindow.show()},
            {
                label: '退出应用', click: () => {
                    app.isQuiting = true; // 标记准备退出
                    app.quit();           // 调用退出
                }
            }
        ]);

        // 设置托盘右键菜单
        tray.setContextMenu(contextMenu);

        // 单击托盘图标显示窗口
        tray.on('click', () => {
            mainWindow.show();
        });

        // 监听窗口关闭事件，不退出，只隐藏
        mainWindow.on('close', (event) => {
            if (!app.isQuiting) {
                event.preventDefault(); // 阻止默认关闭行为
                mainWindow.hide();      // 隐藏窗口
            }
        });

        // 让主窗口加载文件
        mainWindow.loadFile('./src/index.html');

        // 隐藏默认菜单栏
        Menu.setApplicationMenu(null);
    }
};

const gotTheLock = app.requestSingleInstanceLock()
if (!gotTheLock) {
    app.quit()
}
else{
    app.on('second-instance', (event, commandLine, workingDirectory) => {
        // 用户正在尝试运行第二个实例，我们需要让焦点指向我们的窗口
        if (mainWindow) {
            if (mainWindow.isMinimized()) mainWindow.restore(); // 如果窗口最小化，先还原
            mainWindow.focus(); // 聚焦窗口
            mainWindow.show();   // 确保窗口显示出来
        }
    })
}
// 控制ready事件
// ready事件是：当 Electron 完成初始化时，发出一次。
app.on('ready', () => {
    // 新建窗口
    createWindow()
    checkPortInUse(9529, (inUse) => {
        if (!inUse) {
            startWebSocketServer(); // 如果端口未占用，则启动 WebSocket 服务器
        } else {
            console.log('Port 9529 is already in use.');
        }
    });
});
function checkPortInUse(port, callback) {
    const server = net.createServer((socket) => socket.end());

    server.listen(port, (err) => {
        server.close();
        callback(false); // 端口未占用
    });

    server.on('error', (err) => {
        if (err.code === 'EADDRINUSE') {
            callback(true); // 端口已占用
        }
    });
}
// win 关闭事件
app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

// 监听从渲染进程发送的 UDP 消息 然后进行udp消息命令推送 如：开房、关房、转房等  下行指令
ipcMain.on('send-udp-message', (event, {packet, ip, port, room_name}) => {
    console.log(packet)
    const buffer = Buffer.from(packet, 'hex');
    const textMainBytes = buffer.slice(0, 4)
    const textMainLength = textMainBytes.readUInt32LE(0);
    const textSubBytes = buffer.slice(4, 8)
    const textSubLength = textSubBytes.readUInt32LE(0);
    const textContentBytes = buffer.slice(32);
    const textContentUtf8 = textContentBytes.toString('utf8');
    console.log(textContentUtf8)
    console.log(textMainLength)
    console.log(textSubLength)
    let msgStatus = '未知指令'
    if (textMainLength === 0x01 && textSubLength === 0x01) {
        msgStatus = '(' + room_name + ')开房指令'
    }
    if (textMainLength === 0x01 && textSubLength === 0x02) {
        msgStatus = '(' + room_name + ')关房指令'
    }
    if (textMainLength === 0x01 && textSubLength === 0x03) {
        msgStatus = '(' + room_name + ')转房指令'
    }
    if (textMainLength === 0x01 && textSubLength === 0x04) {
        msgStatus = '(' + room_name + ')'
    }
    if (textMainLength === 0x15 && textSubLength === 0x00) {
        msgStatus = '(' + room_name + ')'
    }
    // 服务铃模拟请求
    if (textMainLength === 0x0A && textSubLength === 0x01) {
        msgStatus = '(' + room_name + ')'
    }
    // 服务响应模拟请求
    if (textMainLength === 0x0A && textSubLength === 0x03) {
        msgStatus = '(' + room_name + ')'
    }
    // 呼叫服务反馈发送
    if (textMainLength === 0x0A && textSubLength === 0x02) {
        msgStatus = '(' + room_name + ')'
    }
    // 服务响应反馈
    if (textMainLength === 0x0A && textSubLength === 0x04) {
        msgStatus = '(' + room_name + ')'
    }
    client.send(buffer, port, ip, (err) => {
        if (err) {
            mainWindow.webContents.send('message-from-main-udp', msgStatus + '——下行指令发送失败:' + err);
        } else {
            mainWindow.webContents.send('message-from-main-udp', msgStatus + '——下行指令发送成功:(正文:' + textContentUtf8 + ')');
        }
    })
});

// 监听 udp listening 事件
client.on('listening', () => {
    const address = client.address();
    const content = '服务监听已启动:' + address.address + ':' + address.port;
    // mainWindow.webContents.send('message-from-main-udp', content);
});

// 绑定端口 udp 9528 开始监听
client.bind(9528);

// 监听 udp error 事件
client.on('error', (err) => {
    console.error(`服务启动失败：\n${err.stack}`);
    client.close();
});

// 监听 udp message 事件，接收数据包
client.on('message', (msg, rinfo) => {
    // 主消息号 Buffer
    const mainMessage4Bytes = msg.slice(0, 4);
    console.log('主消息号：' + mainMessage4Bytes.toString('hex'))
    // 子消息号 Buffer
    const subMessage4Bytes = msg.slice(4, 8);
    console.log('子消息号：' + subMessage4Bytes.toString('hex'))
    // 房间ip Buffer
    const roomIp4Bytes = msg.slice(8, 12);
    console.log(roomIp4Bytes.toString('hex'))
    // 房间ip 10进制
    const roomIp = Array.from(roomIp4Bytes).map(byte => byte.toString(10)).join('.');
    console.log('房间IP：' + roomIp)
    // 版本号 Buffer
    const version4Bytes = msg.slice(12, 16);
    console.log('版本号：' + version4Bytes.toString('hex'))
    // 预留字段 Buffer
    const field12Bytes = msg.slice(16, 28);
    console.log('预留字段：' + field12Bytes.toString('hex'))
    // 正文长度 Buffer
    const textLength4Bytes = msg.slice(28, 32);
    console.log('正文长度：' + textLength4Bytes.toString('hex'))
    // 正文内容 Buffer
    const textContentBytes = msg.slice(32);
    // console.log('正文内容：' + textContentBytes.toString('hex'))
    // console.log('正文内容：' + textContentBytes.toString('utf8'))

    // 转换为十进制字符串
    const mainLength = mainMessage4Bytes.readUInt32LE(0);
    const subLength = subMessage4Bytes.readUInt32LE(0);
    console.log(mainLength)
    console.log(subLength)
    // 回复消息内容显示
    const textContentUtf8 = textContentBytes.toString('utf8');
    let messageCallBack = '';
    if (mainLength === 0x0A && subLength === 0x01 && roomIp.length > 0) {
        messageCallBack = '上行接收指令：服务铃呼叫请求(房间ip:' + roomIp + ')' + '(正文:' + textContentUtf8 + ')';
        const data = {
            'status': 'open',
            'room_ip': roomIp,
            'content': textContentUtf8
        }
        mainWindow.webContents.send('message-from-main-udp-status', JSON.stringify(data));
    }
    if (mainLength === 0x0A && subLength === 0x03 && roomIp.length > 0) {
        messageCallBack = '上行接收指令：服务铃响应请求(房间ip:' + roomIp + ')' + '(正文:' + textContentUtf8 + ')';
        const data = {
            'status': 'close',
            'room_ip': roomIp,
            'content': textContentUtf8
        }
        mainWindow.webContents.send('message-from-main-udp-status', JSON.stringify(data));
    }
    if (messageCallBack !== '') {
        mainWindow.webContents.send('message-from-main-udp', messageCallBack);
    } else {
        return false
    }
});
let wsServer;
// web ws server 服务器搭建，通讯开始
const WebSocketServer = require('ws').Server
// 创建 WebSocket 服务器，只在主进程中启动
function startWebSocketServer() {
    if (!wsServer) {
        wsServer = new WebSocketServer({ port: 9529 });
        wsServer.on('connection', (ws) => {
            console.log('New WebSocket connection established.');
            ws.on('message', (message) => {
                const messageString = message.toString('utf8')
                if (messageString === 'pong') {
                    ws.send('pong')
                    return
                }
                let data = JSON.parse(messageString)
                console.log(data)
                // // 直接将消息打印出来
                mainWindow.webContents.send('message-from-main-socket', data)

            })
        });
    }
}

app.on('window-all-closed', () => {
    if (process.platform !== 'darwin') app.quit();
});

